﻿namespace Core.Implementation
{
	using System;
	using System.Collections.Generic;
	using System.Linq;
	using System.Diagnostics.Contracts;
	using Domain;
	using NHibernate;
	using NHibernate.Linq;
	using Providers.DataAccess;	

	internal class NHibernateAccountRepository : AccountRepository
	{

		public NHibernateAccountRepository(IDataAccessProvider dataAccessProvider)
		{
			CodeContract.Requires(dataAccessProvider != null);
			this.DataAccessProvider = dataAccessProvider;
		}

		public IDataAccessProvider DataAccessProvider
		{
			get; 
			private set;
		}

		private class AccountDataContext : NHibernateContext
		{
			public AccountDataContext(ISession session)
			: base(session)
			{
			}

			public IOrderedQueryable<Account> Accounts
			{
				get
				{
					return Session.Linq<Account>();
				}
			}
		}

		private AccountDataContext CreateContext()
		{
			var sessionFactory = this.DataAccessProvider.CreateSessionFactory();

			return new AccountDataContext(sessionFactory.OpenSession());
		}

		public override Account GetByEmail(string email)
		{
			using (var context = CreateContext())
			{
				return context.Accounts.First(a => a.Person.EmailAddress == email);
			}
		}

		public override IEnumerable<Account> EnumerateAccounts()
		{
			throw new NotImplementedException();
		}

		public override bool ContainsWithEmail(string email)
		{
			throw new NotImplementedException();
		}

		public override Account Save(Account account)
		{
			using (var context = CreateContext())
			{
				context.Session.SaveOrUpdate(account);
				context.Session.Flush();
				return context.Accounts.First(a => a.Person.EmailAddress == account.Person.EmailAddress);
			}
		}
	}
}
